package com.dx.esb.m8583;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.dx.esb.m8583.bean.M8583Bean;
import com.dx.esb.m8583.config.Config;
import com.dx.esb.m8583.map.FiledBean;
import com.dx.esb.m8583.map.Map8583Bean;
import com.dx.esb.m8583.model.BitMap;
import com.dx.esb.m8583.type.IsoType;
import com.dx.esb.m8583.util.EncodeUtil;

public class Parse8583 {
	private final static Logger log = LoggerFactory.getLogger(Parse8583.class);
	
	/*private Map paseMeta=new HashMap();
	private List list=new ArrayList();*/
	
	private Config config;
	
	public void initMeta(){
		
		config=new Config();
		try {
			config.parse();
		} catch (Exception e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
		
	}
	
	
	
	public String get8583String(M8583Bean mbean){
		String s8583="";
		
		s8583=mbean.getTpdu();
		
		System.out.println("Tpdu="+s8583);
		
		s8583=s8583+mbean.getHeader();
		
		System.out.println("Header="+s8583);
		
		s8583=s8583+mbean.getType();
		
		System.out.println("Type="+s8583);
		
		BitMap bitArray = new BitMap(64);
		List list=mbean.getFiledList();
		List arrayList=new ArrayList();
		for(int i=0;i<list.size();i++){
			FiledBean fBean=(FiledBean) list.get(i);
			arrayList.add(fBean.getDomain());
		}
		bitArray.addBits(arrayList);
		s8583=s8583+EncodeUtil.hex(bitArray.getBitMap());
		System.out.println("bit="+s8583);
		
		StringBuffer body=new StringBuffer();
		for(int i=0;i<list.size();i++){
			FiledBean filedBean=(FiledBean) list.get(i);
			if(filedBean.getType().name().equalsIgnoreCase(IsoType.LLVAR.name())){
				body.append(filedBean.getObj().toString());
    		}
        	
        	if(filedBean.getType().name().equalsIgnoreCase(IsoType.BINARY.name())){
        		body.append(filedBean.getObj().toString());
    		}
        	
        	
        	if(filedBean.getType().name().equalsIgnoreCase(IsoType.LLLVAR.name())){
        		
        	}
        	
        	if(filedBean.getType().name().equalsIgnoreCase(IsoType.NFIXED.name())){
        		
        	}
        	
        	if(filedBean.getType().name().equalsIgnoreCase(IsoType.NUMERIC.name())){
        		int m=(int) ((Double) filedBean.getObj()*100);
        		int max=filedBean.getLength();
        		int length=max-(m+"").length();
        		StringBuffer value=new StringBuffer();
        		for(int j=0;j<length;j++){
        			value.append("0");
        		}
        		value.append(m+"");
        		body.append(value.toString());
        	}
        	
        	if(filedBean.getType().name().equalsIgnoreCase(IsoType.DATE10.name())){
        		
        	}
        	
        	if(filedBean.getType().name().equalsIgnoreCase(IsoType.DATE4.name())){
        		
        	}
        	
        	if(filedBean.getType().name().equalsIgnoreCase(IsoType.DATE_EXP.name())){
        		
        	}
        	
        	
        	if(filedBean.getType().name().equalsIgnoreCase(IsoType.TIME.name())){
        		
        	}
        	
        	if(filedBean.getType().name().equalsIgnoreCase(IsoType.AMOUNT.name())){
        		
        	}
        	
        	//System.out.println(filedBean.getInfo()+"---"+filedBean.getBcd()+" "+filedBean.getType()+"--"+filedBean.getDomain()+"="+body.toString());
		}
		
		return s8583;
	}
	
	
	
	
	public M8583Bean get8583Bean(String s8583) {
		//String s="60 00 03 00 00 60 31 00 31 07 30 02 00 30 20 04 C0 20 C0 98 11 00 00 00 00 00 00 00 00 01 00 03 49 02 10 00 12 30 62 25 82 21 12 99 63 01 5D 15 11 10 10 00 00 35 36 38 35 32 33 31 34 32 33 35 32 31 34 35 32 36 38 35 39 32 33 36 31 35 36 C6 24 83 4D 36 7E 9E 9E 20 00 00 00 00 00 00 00 00 13 22 00 00 08 00 05 00 36 37 41 32 32 39 39 41";
        //s=s.replaceAll(" ", "");
		M8583Bean m8583Bean=new M8583Bean();
		String s=s8583;
        String tpdu=s.substring(0, 10);
        m8583Bean.setTpdu(tpdu);
        log.debug("tpdu="+tpdu);
        String header=s.substring(10, 22);
        m8583Bean.setHeader(header);
        log.debug("header="+header);
        String body=s.substring(22,s.length());
        log.debug("body="+body);
        
        String type=body.substring(0,4);
        
        log.debug("type="+type);
        m8583Bean.setType(type);
        
        Map8583Bean bean=(Map8583Bean) getConfig().getPaseMeta().get(getConfig().getHeaderMeta().get(type));//(Map8583Bean) test8583.getPaseMeta().get(type);
        
        String bit=body.substring(4,20);
        log.debug("bit="+bit);
        m8583Bean.setBit(bit);
        
        byte[] bts = EncodeUtil.bcd(bit);
		int[] intArr = new int[bts.length*8];
		int curse = 0;
		StringBuilder accum = new StringBuilder();
		for(int i=0;i<8;i++){
			for(int j=7;j>=0;j--){
				intArr[curse++] = (bts[i]>>>j)&0x01;
			}
		}
		
		int c=0;
		List domainFiled=new ArrayList();
		for(int i:intArr){
			if(i==1){
				//accum.append(c+1+",");
				domainFiled.add(""+(c+1));
				//System.out.println(""+(c+1));
			}
			c++;
		}
        
        String domain=body.substring(20,body.length());
        //List list=test8583.getList();
        int start=0;
        
        List filedList=new ArrayList();
        for(int i=0;i<domainFiled.size();i++){
        	//System.out.println("tttt============="+domainFiled.get(i).toString());
        	FiledBean filedBean=bean.getFiledBean(domainFiled.get(i).toString());//(FiledBean) list.get(i);
        	int end=0;
        	
        	if(filedBean.getType().name().equalsIgnoreCase(IsoType.LLVAR.name())){
        		//System.out.println("域"+filedBean.getDomain()+" "+filedBean.getType().name()+" "+filedBean.getLength()+" "+filedBean.getInfo()+" "+filedBean.getBcd());
        		end=start+filedBean.getLength()*2;
        		String filed=domain.substring(start,end);
        		if(filedBean.getBcd()!=null){
        			if(filedBean.getBcd().equalsIgnoreCase("bcdl")){
        				filed=filed.substring(0,filed.length()-1);
        			}
            	}
        		filedBean.setObj(filed);
        		filedList.add(filedBean);
        		System.out.println("域"+filedBean.getDomain()+" value="+filed+" "+filedBean.getType().name()+" "+filedBean.getLength()+" "+filedBean.getInfo()+" "+filedBean.getBcd());
        	    //log.debug("下一步内容="+domain.substring(end,domain.length()));
        	    
    		}
        	
        	if(filedBean.getType().name().equalsIgnoreCase(IsoType.BINARY.name())){
        		//System.out.println("域"+filedBean.getDomain()+" "+filedBean.getType().name()+" "+filedBean.getLength()+" "+filedBean.getInfo()+" "+filedBean.getBcd());
        		end=start+filedBean.getLength()*2;
        		String filed=domain.substring(start,end);
        		if(filedBean.getBcd()!=null){
        			if(filedBean.getBcd().equalsIgnoreCase("bcdl")){
        				filed="0"+filed;
        			}
            	}
        		filedBean.setObj(filed);
        		filedList.add(filedBean);
        		System.out.println("域"+filedBean.getDomain()+" value="+filed+" "+filedBean.getType().name()+" "+filedBean.getLength()+" "+filedBean.getInfo()+" "+filedBean.getBcd());
        	    //log.debug("下一步内容="+domain.substring(end,domain.length()));
        	    
    		}
        	
        	
        	if(filedBean.getType().name().equalsIgnoreCase(IsoType.LLLVAR.name())){
        		//System.out.println("域"+filedBean.getDomain()+" "+filedBean.getType().name()+" "+filedBean.getLength()+" "+filedBean.getInfo()+" "+filedBean.getBcd());
        		end=start+1*2;
        		String len=domain.substring(start, end);
        		 log.debug("域"+filedBean.getDomain()+" "+filedBean.getType().name()+" "+filedBean.getLength()+" "+filedBean.getInfo()+" "+filedBean.getBcd());
        		 log.debug("第二磁道的数据="+len);
        		 int n=Integer.parseInt(len);
        		 start=end;
        		 end=start+n;
        		 String filed=domain.substring(start,end);
        		 filedBean.setObj(filed);
        		 filedList.add(filedBean);
        		 System.out.println("域"+filedBean.getDomain()+" value="+filed+" "+filedBean.getType().name()+" "+filedBean.getLength()+" "+filedBean.getInfo()+" "+filedBean.getBcd());
        	}
        	
        	if(filedBean.getType().name().equalsIgnoreCase(IsoType.NFIXED.name())){
        		//System.out.println("域"+filedBean.getDomain()+" "+filedBean.getType().name()+" "+filedBean.getLength()+" "+filedBean.getInfo()+" "+filedBean.getBcd());
        		end=start+2*2;
        		String len=domain.substring(start, end);
        		 log.debug("域"+filedBean.getDomain()+" "+filedBean.getType().name()+" "+filedBean.getLength()+" "+filedBean.getInfo()+" "+filedBean.getBcd());
        		 log.debug("第二磁道的数据="+len);
        		 int n=Integer.parseInt(len);
        		 start=end;
        		 end=start+n+1;
        		 String filed=domain.substring(start,end);
        		 filedBean.setObj(filed);
        		 filedList.add(filedBean);
        		 //log.debug(str2Bcd(filed));
        		 System.out.println("域"+filedBean.getDomain()+" value="+filed+" "+filedBean.getType().name()+" "+filedBean.getLength()+" "+filedBean.getInfo()+" "+filedBean.getBcd());
        	}
        	
        	if(filedBean.getType().name().equalsIgnoreCase(IsoType.NUMERIC.name())){
        		//System.out.println("域"+filedBean.getDomain()+" "+filedBean.getType().name()+" "+filedBean.getLength()+" "+filedBean.getInfo()+" "+filedBean.getBcd());
        		end=start+filedBean.getLength()*2;
        		String filed=domain.substring(start,end);
        		double p=Double.parseDouble(filed)/100;
        		filedBean.setObj(p);
        		filedList.add(filedBean);
        		System.out.println("域"+filedBean.getDomain()+" value="+p+" "+filedBean.getType().name()+" "+filedBean.getLength()+" "+filedBean.getInfo());
        		
        	}
        	
        	if(filedBean.getType().name().equalsIgnoreCase(IsoType.DATE10.name())){
        		//System.out.println("域"+filedBean.getDomain()+" "+filedBean.getType().name()+" "+filedBean.getLength()+" "+filedBean.getInfo()+" "+filedBean.getBcd());
        		end=start+IsoType.DATE10.getLength()*2;
        		String filed=domain.substring(start,end);
        		filedBean.setObj(filed);
        		filedList.add(filedBean);
        		System.out.println("域"+filedBean.getDomain()+" value="+filed+" "+filedBean.getType().name()+" "+filedBean.getLength()+" "+filedBean.getInfo()+" "+filedBean.getBcd());
        	}
        	
        	if(filedBean.getType().name().equalsIgnoreCase(IsoType.DATE4.name())){
        		//System.out.println("域"+filedBean.getDomain()+" "+filedBean.getType().name()+" "+filedBean.getLength()+" "+filedBean.getInfo()+" "+filedBean.getBcd());
        		end=start+IsoType.DATE4.getLength()*2;
        		String filed=domain.substring(start,end);
        		filedBean.setObj(filed);
        		filedList.add(filedBean);
        		System.out.println("域"+filedBean.getDomain()+" value="+filed+" "+filedBean.getType().name()+" "+filedBean.getLength()+" "+filedBean.getInfo()+" "+filedBean.getBcd());
        	}
        	
        	if(filedBean.getType().name().equalsIgnoreCase(IsoType.DATE_EXP.name())){
        		//System.out.println("域"+filedBean.getDomain()+" "+filedBean.getType().name()+" "+filedBean.getLength()+" "+filedBean.getInfo()+" "+filedBean.getBcd());
        		end=start+IsoType.DATE_EXP.getLength()*2;
        		String filed=domain.substring(start,end);
        		filedBean.setObj(filed);
        		filedList.add(filedBean);
        		System.out.println("域"+filedBean.getDomain()+" value="+filed+" "+filedBean.getType().name()+" "+filedBean.getLength()+" "+filedBean.getInfo()+" "+filedBean.getBcd());
        	}
        	
        	
        	if(filedBean.getType().name().equalsIgnoreCase(IsoType.TIME.name())){
        		//System.out.println("域"+filedBean.getDomain()+" "+filedBean.getType().name()+" "+filedBean.getLength()+" "+filedBean.getInfo()+" "+filedBean.getBcd());
        		end=start+IsoType.TIME.getLength()*2;
        		String filed=domain.substring(start,end);
        		filedBean.setObj(filed);
        		filedList.add(filedBean);
        		System.out.println("域"+filedBean.getDomain()+" value="+filed+" "+filedBean.getType().name()+" "+filedBean.getLength()+" "+filedBean.getInfo()+" "+filedBean.getBcd());
        	}
        	
        	if(filedBean.getType().name().equalsIgnoreCase(IsoType.AMOUNT.name())){
        		//System.out.println("域"+filedBean.getDomain()+" "+filedBean.getType().name()+" "+filedBean.getLength()+" "+filedBean.getInfo()+" "+filedBean.getBcd());
        		end=start+IsoType.AMOUNT.getLength()*2;
        		String filed=domain.substring(start,end);
        		filedBean.setObj(filed);
        		filedList.add(filedBean);
        		System.out.println("域"+filedBean.getDomain()+" value="+filed+" "+filedBean.getType().name()+" "+filedBean.getLength()+" "+filedBean.getInfo()+" "+filedBean.getBcd());
        	}
        	
        	
        	start=end;
        }
        
        m8583Bean.setFiledList(filedList);
        return m8583Bean;
	}
	
	
	
	public static Document m8583ToXML(M8583Bean bean){
		
		Element root = DocumentHelper.createElement("Pos8583"); 
		Document document = DocumentHelper.createDocument(root);  
		
		Element tpduElement = root.addElement("TPDU"); 
		
		tpduElement.setText(bean.getTpdu());
		Element headerElement = root.addElement("HEADER"); 
		headerElement.setText(bean.getHeader());
		
		Element typeElement = root.addElement("TYPE"); 
		
		typeElement.setText(bean.getType());
		
		Element domainElement = root.addElement("Domain"); 
		
		List filedbean=bean.getFiledList();
		for(int i=0;i<filedbean.size();i++){
			FiledBean filedBean=(FiledBean) filedbean.get(i);
			Element filed=domainElement.addElement("Filed");
			filed.setAttributeValue("domain", ""+filedBean.getDomain());
			filed.setAttributeValue("type", ""+filedBean.getType().name());
			filed.setAttributeValue("length", ""+filedBean.getLength());
			if(filedBean.getBcd()!=null){
				filed.setAttributeValue("bcd", filedBean.getBcd());
			}
			filed.setText(filedBean.getObj().toString());
			//System.out.println("域"+filedBean.getDomain()+" value="+filedBean.getObj()+" "+filedBean.getType().name()+" "+filedBean.getLength()+" "+filedBean.getInfo()+" "+filedBean.getBcd());
		}
		
		return document;
	}
	

	/**
	 * @功能: BCD码转为10进制串(阿拉伯数据)
	 * @参数: BCD码
	 * @结果: 10进制串
	 */
	public static String bcd2Str(byte[] bytes) {
		StringBuffer temp = new StringBuffer(bytes.length * 2);
		for (int i = 0; i < bytes.length; i++) {
			temp.append((byte) ((bytes[i] & 0xf0) >>> 4));
			temp.append((byte) (bytes[i] & 0x0f));
		}
		return temp.toString().substring(0, 1).equalsIgnoreCase("0") ? temp
				.toString().substring(1) : temp.toString();
	}

	/**
	 * @功能: 10进制串转为BCD码
	 * @参数: 10进制串
	 * @结果: BCD码
	 */
	public static byte[] str2Bcd(String asc) {
		int len = asc.length();
		int mod = len % 2;
		if (mod != 0) {
			asc = "0" + asc;
			len = asc.length();
		}
		byte abt[] = new byte[len];
		if (len >= 2) {
			len = len / 2;
		}
		byte bbt[] = new byte[len];
		abt = asc.getBytes();
		int j, k;
		for (int p = 0; p < asc.length() / 2; p++) {
			if ((abt[2 * p] >= '0') && (abt[2 * p] <= '9')) {
				j = abt[2 * p] - '0';
			} else if ((abt[2 * p] >= 'a') && (abt[2 * p] <= 'z')) {
				j = abt[2 * p] - 'a' + 0x0a;
			} else {
				j = abt[2 * p] - 'A' + 0x0a;
			}
			if ((abt[2 * p + 1] >= '0') && (abt[2 * p + 1] <= '9')) {
				k = abt[2 * p + 1] - '0';
			} else if ((abt[2 * p + 1] >= 'a') && (abt[2 * p + 1] <= 'z')) {
				k = abt[2 * p + 1] - 'a' + 0x0a;
			} else {
				k = abt[2 * p + 1] - 'A' + 0x0a;
			}
			int a = (j << 4) + k;
			byte b = (byte) a;
			bbt[p] = b;
		}
		return bbt;
	}
	
	/*public Object getValue(String filed,FiledBean filedBean){
		if(filedBean.getType().name().equalsIgnoreCase(IsoType.LLVAR.name())){
			
		}
		return null;
	}*/


	/*public Map getPaseMeta() {
		return paseMeta;
	}


	public void setPaseMeta(Map paseMeta) {
		this.paseMeta = paseMeta;
	}


	public List getList() {
		return list;
	}


	public void setList(List list) {
		this.list = list;
	}*/
	
	public static void main(String[] args){
		String s8583="60 00 03 00 00 60 31 00 31 07 30 02 00 30 20 04 C0 20 C0 98 11 00 00 00 00 00 00 00 00 01 00 03 49 02 10 00 12 30 62 25 82 21 12 99 63 01 5D 15 11 10 10 00 00 35 36 38 35 32 33 31 34 32 33 35 32 31 34 35 32 36 38 35 39 32 33 36 31 35 36 C6 24 83 4D 36 7E 9E 9E 20 00 00 00 00 00 00 00 00 13 22 00 00 08 00 05 00 36 37 41 32 32 39 39 41";
		s8583=s8583.replaceAll(" ", "");
		Parse8583 parse8583=new Parse8583();
		parse8583.initMeta();
		M8583Bean mbean = null;
		try {
			mbean = parse8583.get8583Bean(s8583);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("tpdu="+mbean.getTpdu());
		System.out.println("header="+mbean.getHeader());
		System.out.println("type="+mbean.getType());
		System.out.println("bit="+mbean.getBit());
		System.out.println();
		List filedbean=mbean.getFiledList();
		for(int i=0;i<filedbean.size();i++){
			FiledBean filedBean=(FiledBean) filedbean.get(i);
			System.out.println("域"+filedBean.getDomain()+" value="+filedBean.getObj()+" "+filedBean.getType().name()+" "+filedBean.getLength()+" "+filedBean.getInfo()+" "+filedBean.getBcd());
		}
		
		Document dom=Parse8583.m8583ToXML(mbean);
		dom.setXMLEncoding("UTF-8");
		System.out.println(dom.asXML());
	}


	public Config getConfig() {
		return config;
	}


	public void setConfig(Config config) {
		this.config = config;
	}
}
